﻿using Biotech.Log;
using MaterialDesignThemes.Wpf;
using Microsoft.Win32;
using NPOI.SS.Formula.Functions;
using OfficeOpenXml;
using project.B12.application.Ioc;
using project.B12.IRepository;
using project.B12.IService;
using project.B12.Model.Enums;
using project.B12.Model.Models;
using project.B12.ViewModels;
using software.Common.MVVM;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Windows;

namespace project.B12.application.ViewModels.Dialogs
{
    public class ReportExportTemplateViewModel : ObservableObject
    {
        private IServiceImageProcessing _serviceImageProcessing;
        private IHisRepository _hisRepository;
        private IMICPlateMes _mICPlateMes;
        private IWorkSequence _workSequence;
        private IServiceIdentification _serviceIdentification;
        private IResultReportedRepository _resultReportedRepository;
        private PublicResourceViewModel _publicResourceViewModel;

        public ReportExportTemplateViewModel(
            IServiceImageProcessing serviceImageProcessing,
            IHisRepository hisRepository,
            IMICPlateMes mICPlateMes,
            IWorkSequence workSequence,
            IServiceIdentification serviceIdentification,
            IResultReportedRepository resultReportedRepository)
        {
            _serviceImageProcessing = serviceImageProcessing;
            _hisRepository = hisRepository;
            _mICPlateMes = mICPlateMes;
            _workSequence = workSequence;
            _serviceIdentification = serviceIdentification;
            _resultReportedRepository = resultReportedRepository;
            _publicResourceViewModel = ViewModelLocator.PublicResourceViewModel;
        }

        private DateTime? startDatePickerValue;
        public DateTime? StartDatePickerValue
        {
            get { return startDatePickerValue; }
            set
            {
                startDatePickerValue = value;
                this.RaisePropertyChanged();
            }
        }

        private DateTime? endDatePickerValue;
        public DateTime? EndDatePickerValue
        {
            get { return endDatePickerValue; }
            set
            {
                endDatePickerValue = value;
                this.RaisePropertyChanged();
            }
        }

        private string type { get; set; }
        public string Type
        {
            get { return type; }
            set
            {
                type = value;
                this.RaisePropertyChanged();
            }
        }

        private string hospital { get; set; }
        public string Hospital
        {
            get { return hospital; }
            set
            {
                hospital = value;
                this.RaisePropertyChanged();
            }
        }

        private string remark { get; set; }
        public string Remark
        {
            get { return remark; }
            set
            {
                remark = value;
                this.RaisePropertyChanged();
            }
        }

        public RelayCommand Export => new RelayCommand(ExportReport);
        public RelayCommand Cancel => new RelayCommand(Exit);

        private void ExportReport()
        {
            #region 导入数据库
            //string filePath = @"C:\Users\16320\Desktop\test.xlsx";
            //FileInfo existingFile = new FileInfo(filePath);
            //ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
            //using (ExcelPackage package = new ExcelPackage(existingFile))
            //{
            //    // 获取Excel文件中的第一个工作表
            //    int number= package.Workbook.Worksheets.Count;
            //    for(int i=0;i< number;i++)
            //    {
            //        ExcelWorksheet worksheet = package.Workbook.Worksheets[i];
            //        for (int row = 2; row <= worksheet.Dimension.End.Row; row++)
            //        {
            //            Table_ResultReported reported = new Table_ResultReported()
            //            {
            //                PlateType = worksheet.Cells[row, 1].Value.ToString(),
            //                PlateId = worksheet.Cells[row, 2].Value.ToString(),
            //                SampleId = worksheet.Cells[row, 3].Value.ToString(),
            //                LoadTime = DateTime.Parse(worksheet.Cells[row, 4].Value.ToString()),
            //                BacterialName = worksheet.Cells[row, 6].Value.ToString(),
            //            };
            //            Dictionary<string, string> results = new Dictionary<string, string>();
            //            for (int col = 9; col <= worksheet.Dimension.End.Column; col++)
            //            {
            //                string name = worksheet.Cells[1, col].Value.ToString();
            //                string mic = worksheet.Cells[row, col].Value.ToString();
            //                results.Add(name, mic);
            //            }
            //            reported.MicResult = results;
            //            _resultReportedRepository.AddReport(reported);
            //        }
            //    }
            //}
            #endregion

            #region
            /*     try
                 {
                     string filePath = null;
                     SaveFileDialog openFileDialog = new SaveFileDialog
                     {
                         Title = "选择一个文件",
                         InitialDirectory = AppDomain.CurrentDomain.BaseDirectory + @"Export",
                         Filter = "Excel工作表(*.xlsx)|*.xlsx"
                     };

                     if (openFileDialog.ShowDialog() == true)
                     {
                         filePath = openFileDialog.FileName;
                         File.Create(filePath).Close();
                     }
                     else
                         return;

                     List<Table_ResultReported> results = _resultReportedRepository.QueryReportByTime(StartDatePickerValue, EndDatePickerValue);

                     //string[] names= _serviceImageProcessing.GetFileNamesByTime(AppDomain.CurrentDomain.BaseDirectory + @"Image", StartDatePickerValue, EndDatePickerValue);
                     ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
                     using (ExcelPackage package = new ExcelPackage(new FileInfo(filePath)))
                     {
                         ExcelWorkbook workbook = package.Workbook;
                         if (workbook.Worksheets.Count() > 0)
                         {
                             for (int i = 0; i < workbook.Worksheets.Count(); i++)
                             {
                                 workbook.Worksheets.Delete(i);
                             }
                         }

                         foreach (var item in results)
                         {
                             ExcelWorksheet sheet = null;
                             string plateType = item.PlateType;
                             if (workbook.Worksheets[plateType] == null)
                             {
                                 sheet = workbook.Worksheets.Add(plateType);
                                 SetReportSheet(sheet, item);
                             }
                             else
                                 sheet = workbook.Worksheets.FirstOrDefault(o => o.Name == plateType);

                             //结果报告导入工作表
                             int rowIndex = sheet.Dimension.Rows;
                             SetReportMessage(sheet, item, rowIndex + 1);
                         }

                         #region 导出
                         //foreach (var name in names)
                         //{
                         //    int index = name.IndexOf("&");
                         //    string plateId = name.Substring(index + 1);
                         //    if (name.Contains("-"))
                         //    {
                         //        int endIndex = name.LastIndexOf("-");
                         //        plateId = name.Substring(index + 1, endIndex - index - 1);
                         //    }
                         //    string sampleId = name.Substring(0, index);
                         //    var hisories = _hisRepository.QueryHisByPlateName(plateId, sampleId);
                         //    if (hisories == null || hisories.Count == 0)
                         //    {
                         //        WPF.Controls.Message.Push($"未找到“{name}”数据记录！", MessageBoxImage.Warning);
                         //        continue;
                         //    }
                         //    var hisory = hisories.First();
                         //    List<Test> report = new List<Test>();
                         //    if (_publicResourceViewModel.Reports.ContainsKey(name))
                         //        report = _publicResourceViewModel.Reports[name];
                         //    else
                         //        report = GetReport(hisory, name);

                         //    //获取工作表
                         //    ExcelWorksheet sheet = null;
                         //    string plateType = hisory.PlateType;
                         //    if (workbook.Worksheets[plateType] == null)
                         //    {
                         //        sheet = workbook.Worksheets.Add(plateType);
                         //        SetSheet(sheet, report);
                         //    }
                         //    else
                         //        sheet = workbook.Worksheets.FirstOrDefault(o => o.Name == plateType);

                         //    //结果报告导入工作表
                         //    int rowIndex = sheet.Dimension.Rows;
                         //    SetReportForSheet(sheet, report, rowIndex+1, hisory);
                         //}
                         #endregion
                         package.SaveAs(filePath);
                     }
                     MessageBox.Show("导出成功");
                 }
                 catch (Exception ex)
                 {
                     LoggerFactory.Instance.CurrentLogger.LogInfo("分析结果导出失败\n" + ex.ToString(), "", "软件");
                 }*/
            #endregion
            try
            {
                SaveFileDialog saveFileDialog = new SaveFileDialog
                {
                    Title = "选择保存位置",
                    InitialDirectory = AppDomain.CurrentDomain.BaseDirectory + @"Export",
                    Filter = "Excel工作表(*.xlsx)|*.xlsx",
                    DefaultExt = ".xlsx"
                };

                if (saveFileDialog.ShowDialog() != true)
                    return;

                string filePath = saveFileDialog.FileName;

                // 查询数据库获取结果
                List<Table_ResultReported> results = _resultReportedRepository.QueryReportByTime(
                    StartDatePickerValue, EndDatePickerValue);

                // 检查是否有数据
                if (results == null || results.Count == 0)
                {
                    MessageBox.Show("没有找到符合条件的结果报告");
                    return;
                }

                ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
                using (ExcelPackage package = new ExcelPackage())
                {
                    ExcelWorkbook workbook = package.Workbook;

                    // 按板类型分组处理
                    var groupedResults = results.GroupBy(r => r.PlateType);

                    foreach (var group in groupedResults)
                    {
                        // 创建对应板类型的工作表
                        ExcelWorksheet sheet = workbook.Worksheets.Add(group.Key);

                        // 设置表头
                        SetReportSheet(sheet, group.First());

                        // 填充数据
                        int rowIndex = 2; // 从第2行开始（第1行为表头）
                        foreach (var item in group)
                        {
                            SetReportMessage(sheet, item, rowIndex);
                            rowIndex++;
                        }
                    }

                    // 保存文件
                    package.SaveAs(new FileInfo(filePath));
                }

                MessageBox.Show("导出成功");
            }
            catch (Exception ex)
            {
                LoggerFactory.Instance.CurrentLogger.LogInfo("分析结果导出失败\n" + ex.ToString(), "", "软件");
                MessageBox.Show("导出失败：" + ex.Message);
            }
        }

        private void SetReportSheet(ExcelWorksheet sheet, Table_ResultReported report)
        {
            sheet.Cells[1, 1].Value = "项目名称";
            sheet.Cells[1, 2].Value = "板ID";
            sheet.Cells[1, 3].Value = "样本编号";
            sheet.Cells[1, 4].Value = "日期";
            sheet.Cells[1, 5].Value = "标本类型";
            sheet.Cells[1, 6].Value = "菌株名称";
            sheet.Cells[1, 7].Value = "备注";
            sheet.Cells[1, 8].Value = "医院";
            //int index = 1;
            //if (_publicResourceViewModel.ReportTitleRows.ContainsKey(report.PlateType))
            //{
            //    foreach (var item in _publicResourceViewModel.ReportTitleRows)
            //    {
            //        sheet.Cells[1, 8 + index].Value = item.Key;
            //        index++;
            //    }
            //}
            //else
            //{
            //    foreach (var item in report.MicResult)
            //    {
            //        sheet.Cells[1, 8 + index].Value = item.Key;
            //        index++;
            //    }
            //}

            // 设置药物表头 - 根据第二张图片中的药物顺序
            List<string> drugNames = new List<string>
            {
                "AMP", "SAM", "TZP", "CZO", "CXM", "CRO", "FEP", "CSI",
                "CHL", "GEN", "LVX", "SXT", "MEM", "TGC", "NIT", "AMK"
            };

            int colIndex = 9;
            foreach (string drugName in drugNames)
            {
                sheet.Cells[1, colIndex].Value = drugName;
                colIndex++;
            }
        }

        private void SetReportMessage(ExcelWorksheet sheet, Table_ResultReported report, int rowIndex)
        {
            /*sheet.Cells[rowIndex, 1].Value = report.PlateType;
            sheet.Cells[rowIndex, 2].Value = report.PlateId;
            sheet.Cells[rowIndex, 3].Value = report.SampleId;
            sheet.Cells[rowIndex, 4].Value = report.LoadTime.ToString("yyyy/MM/dd");
            sheet.Cells[rowIndex, 5].Value = Type;
            sheet.Cells[rowIndex, 6].Value = report.BacterialName;
            sheet.Cells[rowIndex, 8].Value = Hospital;
            if (report.IsUpdate)
                sheet.Cells[rowIndex, 7].Value = Remark + "手动更正";
            else
                sheet.Cells[rowIndex, 7].Value = Remark;

            int index = 1;
            foreach (var value in report.MicResult)
            {
                string drugName = sheet.Cells[1, 8 + index].Value.ToString();
                if (value.Key == drugName)
                    sheet.Cells[rowIndex, 8 + index].Value = value.Value;
                else
                {
                    var temp = sheet.Cells.FirstOrDefault(o => o.Value == value.Key);
                    temp.Value = value.Value;
                }
                index++;
            }*/


            // 填充基本信息
            sheet.Cells[rowIndex, 1].Value = report.PlateType;
            sheet.Cells[rowIndex, 2].Value = report.PlateId;
            sheet.Cells[rowIndex, 3].Value = report.SampleId;
            sheet.Cells[rowIndex, 4].Value = report.LoadTime.ToString("yyyy/MM/dd");
            sheet.Cells[rowIndex, 5].Value = Type;
            sheet.Cells[rowIndex, 6].Value = report.BacterialName;
            sheet.Cells[rowIndex, 7].Value = report.IsUpdate ? GetRemark() + "手动更正" : GetRemark();
            sheet.Cells[rowIndex, 8].Value = Hospital;

            // 填充药物MIC值
            List<string> drugNames = new List<string>
            {
                "AMP", "SAM", "TZP", "CZO", "CXM", "CRO", "FEP", "CSI",
                "CHL", "GEN", "LVX", "SXT", "MEM", "TGC", "NIT", "AMK"
            };

            int colIndex = 9;
            foreach (string drugName in drugNames)
            {
                if (report.MicResult.ContainsKey(drugName))
                {
                    sheet.Cells[rowIndex, colIndex].Value = report.MicResult[drugName];
                }
                else
                {
                    sheet.Cells[rowIndex, colIndex].Value = "/";
                }
                colIndex++;
            }

        }


        private string GetSpecimenType()
        {
            // 从界面获取标本类型值
            return "咽拭子"; // 示例值，根据实际情况实现
        }

        private string GetHospital()
        {
            // 从界面获取医院值
            return "示例医院"; // 示例值，根据实际情况实现
        }

        private string GetRemark()
        {
            // 从界面获取备注值
            return ""; // 示例值，根据实际情况实现
        }


        private void SetReportForSheet(ExcelWorksheet sheet, List<Test> report, int rowIndex, Table_His hisory)
        {
            if (report == null || report.Count == 0)
                return;

            if (!hisory.IsSpecialSample)
            {
                SetBaseSheet(sheet, rowIndex, hisory, report);
                for (int i = 0; i < report.Count; i++)
                {
                    sheet.Cells[rowIndex, i + 9].Value = report[i].MIC;
                }
                return;
            }

            var temps = report.GroupBy(o => o.BacteriaName, (bacteriaName, list) => new { BacteriaName = bacteriaName, List = list }).ToList();
            for (int i = 0; i < temps.Count; i++)
            {
                SetBaseSheet(sheet, rowIndex + i, hisory, temps[i].List.ToList());
                sheet.Cells[rowIndex + i, 6].Value = temps[i].BacteriaName;

                for (int j = 9; j <= sheet.Dimension.Columns; j++)
                {
                    if (temps[i].List.Any(o => o.DrugName == sheet.Cells[1, j].Value.ToString()))
                    {
                        sheet.Cells[rowIndex + i, j].Value = temps[i].List.FirstOrDefault(o => o.DrugName == sheet.Cells[1, j].Value.ToString()).MIC;
                    }
                }
            }
        }

        private void SetBaseSheet(ExcelWorksheet sheet, int rowIndex, Table_His hisory, List<Test> report)
        {
            sheet.Cells[rowIndex, 1].Value = hisory.PlateType;
            sheet.Cells[rowIndex, 2].Value = hisory.PlateName;
            sheet.Cells[rowIndex, 3].Value = hisory.BacterialID;
            sheet.Cells[rowIndex, 4].Value = hisory.LoadTime.ToString("yyyy/MM/dd");
            sheet.Cells[rowIndex, 5].Value = Type;
            sheet.Cells[rowIndex, 6].Value = hisory.BacterialName;
            sheet.Cells[rowIndex, 8].Value = Hospital;
            if (report.Any(o => o.IsUpdate == true))
            {
                sheet.Cells[rowIndex, 7].Value = Remark + "手动更正";
            }
            else
                sheet.Cells[rowIndex, 7].Value = Remark;
        }

        private void SetSheet(ExcelWorksheet sheet, List<Test> report)
        {
            sheet.Cells[1, 1].Value = "项目名称";
            sheet.Cells[1, 2].Value = "板ID";
            sheet.Cells[1, 3].Value = "样本编号";
            sheet.Cells[1, 4].Value = "日期";
            sheet.Cells[1, 5].Value = "标本类型";
            sheet.Cells[1, 6].Value = "菌株名称";
            sheet.Cells[1, 7].Value = "备注";
            sheet.Cells[1, 8].Value = "医院";

            for (int i = 0; i < report.Count; i++)
            {
                sheet.Cells[1, i + 9].Value = report[i].DrugName;
            }
        }

        private List<Test> GetReport(Table_His hisory, string name)
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + @"Image\" + name;
            string waitProgress = null;
            var resultList = _serviceIdentification.Identification_All(path, hisory.PlateType, hisory.BacterialName, newProgress =>
            {
                //回调中修改 WaitProgress 的值
                waitProgress = newProgress;
            });
            if (!_mICPlateMes.microplateAntibioticConcentrationMes.Any(m => m.name == hisory.PlateType))
            {
                WPF.Controls.Message.Push($"{hisory.PlateType}项目类型不存在，请检查", MessageBoxImage.Warning);
                return null;
            }
            MicroplateMes microMes = _mICPlateMes.microplateAntibioticConcentrationMes.Where(m => m.name == hisory.PlateType).FirstOrDefault();
            List<Test> tests = new List<Test>();
            for (int i = 0; i < resultList.Length; i++)
            {
                string drugName = microMes.antibiotic_concentration[i].Antibiotic.Contains(",") ?
                    microMes.antibiotic_concentration[i].Antibiotic.Split(',')[0] : microMes.antibiotic_concentration[i].Antibiotic;
                Test temp = new Test()
                {
                    Result = resultList[i].ret,
                    DrugName = drugName,
                    DrugConcentration = microMes.antibiotic_concentration[i].Antibiotic.Contains(",") ?
                    float.Parse(microMes.antibiotic_concentration[i].Antibiotic.Split(',')[1]) : null
                };
                tests.Add(temp);
            }

            List<Test> report = new List<Test>();
            if (hisory.IsSpecialSample)
            {
                Dictionary<int, string> bacteriaIndex = hisory.SpecialSampleTypes
                                   .SelectMany(kv => kv.Value.Select(num => new { Number = num, Name = kv.Key })
                                   .OrderBy(x => x.Number)).ToDictionary(o => o.Number, o => o.Name);
                report = GetSpecialReport(tests, bacteriaIndex, hisory.PlateType, null);
            }
            else
            {
                report = GetSpecialReport(tests, null, hisory.PlateType, hisory.BacterialName);
            }
            return report;
        }


        private List<Test> GetSpecialReport(List<Test> tests, Dictionary<int, string> bacteriaIndex, string plateType, string bacteriaName)
        {
            var DrugNameGroup = tests.GroupBy(s => s.DrugName, (drugName, list) => new { DrugName = drugName, List = list }).ToList();
            var length = DrugNameGroup.Count();
            int index = 0;
            List<Test> report = new List<Test>();
            for (int i = 0; i < DrugNameGroup.Count(); i++)
            {
                string mic = string.Empty;
                if (DrugNameGroup[i].DrugName == "+" || DrugNameGroup[i].DrugName == "-")
                {
                    continue;
                }
                index++;

                //浓度从低到高排序
                var ND = DrugNameGroup[i].List.OrderBy(o => o.DrugConcentration).ToList();
                mic = GetMIC(ND);
                string name = string.IsNullOrEmpty(bacteriaName) ? bacteriaIndex[index] : bacteriaName;
                Table_SIR tbSIR = _workSequence.GetSIR(name, DrugNameGroup[i].DrugName);

                float low;
                float high;
                if (tbSIR != null)
                {
                    low = float.Parse(tbSIR.S);
                    high = float.Parse(tbSIR.R);
                }
                else
                {
                    report.Add(new Test()
                    {
                        DrugName = DrugNameGroup[i].DrugName,
                        BacteriaName = name,
                        SIRResult = null,
                        MIC = mic,
                    });
                    continue;
                }
                report.Add(new Test()
                {
                    DrugName = DrugNameGroup[i].DrugName,
                    BacteriaName = name,
                    SIRResult = GetSIRFinally(mic, low, high),
                    MIC = mic,
                });

            }
            return report;
        }

        private string GetMIC(List<Test> ND)
        {
            string mic = string.Empty;
            for (int i = 0; i < ND.Count; i++)
            {
                string[] rets = ND[i].Result.Split('/');
                if (Math.Max(byte.Parse(rets[0]), byte.Parse(rets[1])) < 4)
                {
                    if (i == 0)
                    {
                        mic = $"≤{ND[i].DrugConcentration}";
                    }
                    else
                    {
                        mic = $"{ND[i].DrugConcentration}";
                    }
                    break;
                }
                if (i == (ND.Count - 1))
                {
                    mic = $"≥{ND[i].DrugConcentration}";
                }
            }
            return mic;
        }

        private string GetSIRFinally(string mic, float low, float high)
        {
            string SIR_finally = null;
            if (mic.Contains("≤") && float.Parse(mic.Split('≤')[1]) <= low)
            {
                SIR_finally = SIREnum.敏感.ToString();
            }
            else if (mic.Contains("≥") && float.Parse(mic.Split('≥')[1]) >= high)
            {
                SIR_finally = SIREnum.耐药.ToString();
            }
            else if (float.Parse(mic) <= low)
            {
                SIR_finally = SIREnum.敏感.ToString();
            }
            else if (float.Parse(mic) >= high)
            {
                SIR_finally = SIREnum.耐药.ToString();
            }
            else
            {
                SIR_finally = SIREnum.中介.ToString();
            }
            return SIR_finally;
        }

        private void Exit()
        {
            if (DialogHost.IsDialogOpen("Main"))
                DialogHost.Close("Main", true);
        }
    }
}
